import wave
import threading
import tkinter
import tkinter.filedialog
import tkinter.messagebox
import pyaudio

root = tkinter.Tk()
root.title('Recorder')
root.geometry('270x80+550+300')
root.resizable(False, False)

fileName = None
allowRecording = False  # 录音状态
CHUNK_SIZE = 1024  # 数据块大小
CHANNELS = 2  # 频道
FORMAT = pyaudio.paInt16  # 16位量化编码
RATE = 44100  # 音频采样率


def record():
    global fileName
    p = pyaudio.PyAudio()

    # audio流对象
    stream = p.open(format=FORMAT,
                    channels=CHANNELS,
                    rate=RATE,
                    input=True,
                    frames_per_buffer=CHUNK_SIZE)

    # 音频文件对象
    wf = wave.open(fileName, 'wb')
    wf.setnchannels(CHANNELS)
    wf.setsampwidth(p.get_sample_size(FORMAT))
    wf.setframerate(RATE)

    # 读取数据写入文件
    while allowRecording:
        data = stream.read(CHUNK_SIZE)
        wf.writeframes(data)
    wf.close()
    stream.stop_stream()
    stream.close()
    p.terminate()
    fileName = None


def start():
    global allowRecording, fileName
    #fileName = tkinter.filedialog.asksaveasfilename(filetypes=[('未压缩波形文件', '*.wav')])
    fileName = 'D:/recorder cache/testing.wav'
    if not fileName:
        return
    if not fileName.endswith('.wav'):
        fileName = fileName + '.wav'
    allowRecording = True
    lbStatus['text'] = 'Recording...'
    threading.Thread(target=record).start()


def stop():
    global allowRecording
    allowRecording = False
    lbStatus['text'] = 'Ready'
    print(fileName)


# 关闭程序时检查是否正在录制
def closeWindow():
    if allowRecording:
        tkinter.messagebox.showerror('Recording', 'Please stop recording before close the window.')
        return
    root.destroy()


btnStart = tkinter.Button(root, text='Start', command=start)
btnStart.place(x=30, y=20, width=100, height=20)
btnStop = tkinter.Button(root, text='Stop', command=stop)
btnStop.place(x=140, y=20, width=100, height=20)
lbStatus = tkinter.Label(root, text='Ready', anchor='w', fg='green')  # 靠左显示绿色状态字
lbStatus.place(x=30, y=50, width=200, height=20)
root.protocol('WM_DELETE_WINDOW', closeWindow)

root.mainloop()